package com.zhoug.common3.screenrecord;

import android.content.Context;
import android.content.Intent;
import android.hardware.display.DisplayManager;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Build;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.view.WindowManager;

import com.zhoug.common3.utils.FileUtils;
import com.zhoug.common3.utils.LogUtils;

import java.io.File;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;


/**
 * 录屏工具
 * @Author: zhoug
 * @Date: 2024-09-03
 * @Description:
 */
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class ScreenRecordUtils {
    private static final String TAG = ">>>ScreenRecordUtils";
    private final Context mContext;
    private MediaRecorder mMediaRecorder;
    private MediaProjection mMediaProjection;
    private Intent resultData;
    private int resultCode;
    private String mVideoKeepPath;//视频保存地址

    private int width;
    private int height;
    private int bitRate;//默认2*width*height
    private int frameRate = 30;//30fps

    private boolean isRecording;//标记正在录屏


    public ScreenRecordUtils(@NonNull Context context) {
        this.mContext = context;
    }

    public void setScreenCaptureIntentResult(int resultCode, Intent resultData) {
        this.resultCode = resultCode;
        this.resultData = resultData;
    }

    public void setSize(int width, int height) {
        if (width > 0 && height > 0) {
            this.width = width;
            this.height = height;
        }
    }

    public void setBitRate(int bitRate) {
        this.bitRate = bitRate;
    }

    public void setFrameRate(int frameRate) {
        this.frameRate = frameRate;
    }


    /**
     * 视频保存地址
     *
     * @param videoKeepPath
     */
    public void setVideoKeepPath(String videoKeepPath) {
        this.mVideoKeepPath = videoKeepPath;
    }

    /**
     * 视频保存地址
     *
     * @return
     */
    public String getVideoKeepPath() {
        return mVideoKeepPath;
    }

    public boolean isRecording() {
        return isRecording;
    }


    /**
     * 初始化录像机录音机 开始录屏
     */
    public void startRecorder() throws Exception {
        if (isRecording) return;
        MediaProjectionManager mMediaProjectionManager = (MediaProjectionManager) mContext.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        if (null == mMediaProjectionManager) {
            throw new NullPointerException("实例化录屏管理器失败");
        }
        mMediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, resultData);
        if (null == mMediaProjection) {
            throw new NullPointerException("实例化多媒体投影失败");
        }
        DisplayMetrics displayMetrics = null;
        WindowManager manager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        if (manager != null) {
            displayMetrics = new DisplayMetrics();
            manager.getDefaultDisplay().getMetrics(displayMetrics);
        }

        int dpi = displayMetrics != null ? displayMetrics.densityDpi : 360;
        if (width <= 0) {
            width = displayMetrics == null ? 1080 : displayMetrics.widthPixels;
        }
        //不是偶数会报错
        if (width % 2 != 0) {
            width = width - 1;
        }
        if (height <= 0) {
            height = displayMetrics == null ? 1920 : displayMetrics.heightPixels;
        }
        //不是偶数会报错
        if (height % 2 != 0) {
            height = height - 1;
        }
        if (bitRate <= 0) {
            bitRate = 2 * width * height; //2Mbps
        }
        if (frameRate <= 0) {
            frameRate = 30; // 30fps
        }

        if (mVideoKeepPath == null) {
            File folder = FileUtils.getAppExternalFilesDir(mContext,Environment.DIRECTORY_MOVIES);
            if (folder != null) {
                File file = new File(folder, System.currentTimeMillis() + ".mp4");
                mVideoKeepPath = file.getAbsolutePath();
            }
        }
        File file=new File(mVideoKeepPath);
        File parentFile = file.getParentFile();
        if(parentFile!=null && !parentFile.exists()){
            LogUtils.d(TAG, "startRecorder:创建文件夹");
            boolean mkdirs = parentFile.mkdirs();
            if(!mkdirs){
                throw new Exception("创建录屏文件存储地址失败");
            }
        }

        mMediaRecorder = new MediaRecorder();
        //设置音频来源
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        //设置视频来源
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        //设置视频格式
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        //设置视频存储地址
        mMediaRecorder.setOutputFile(mVideoKeepPath);
        //设置视频大小清晰度
        mMediaRecorder.setVideoSize(width, height);
        //设置视频编码h264
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        //设置音频编码
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        //设置视频码率
        mMediaRecorder.setVideoEncodingBitRate(bitRate);
        //设置视频帧率
        mMediaRecorder.setVideoFrameRate(frameRate);

        try {
            mMediaRecorder.prepare();
            //根据获取的屏幕参数创建虚拟的录屏屏幕
            mMediaProjection.createVirtualDisplay("VirtualScreen", width, height, dpi,
                    DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mMediaRecorder.getSurface(), null, null
            );
            mMediaRecorder.start();
            isRecording = true;
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("录像机初始化失败");
        }
    }

    /**
     * 停止录屏
     */
    public void stopRecord() {
        if (isRecording) {
            if (mMediaRecorder != null) {
                mMediaRecorder.stop();
                mMediaRecorder.release();
                mMediaRecorder = null;
            }
            if (mMediaProjection != null) {
                mMediaProjection.stop();
                mMediaProjection = null;
            }
            isRecording = false;
        }
    }


}
